import pandas as pd
import numpy as np
from numpy import array
import math
from itertools import combinations
from functools import reduce
import datetime
def main(type):
    #DispathJob.py
    message = ''
    table_1 = []
    # 读取已知条件
    xlsx_name = 'D:/repos/sicost/主机相关数据.xlsx'
    df_m = pd.read_excel(xlsx_name)
    xlsx_name = 'D:/repos/sicost/服务相关数据.xlsx'
    df_s = pd.read_excel(xlsx_name)
    # 由于copy_size可能是1.5，所以主机资源量*2，copy_size*2
    df_m['RESOURCE'] = df_m['RESOURCE'] * 2
    df_s['COPY_SIZE'] = df_s['COPY_SIZE'] * 2
    # 反亲和逻辑修改，可以超过主机数，超过主机数时，超过部分可视为非反亲和服务
    # 对主机排序
    df_m_1 = df_m.copy()
    df_m_1 = df_m_1.reset_index(drop=False)
    df_m_1.rename(columns={'index': 'MACHINE_NO'}, inplace=True)
    df_m_1['RESOURCE_MAX'] = df_m_1['RESOURCE'] * df_m_1['U_MAX'] / 100
    df_m_1['RESOURCE_THEORY'] = df_m_1['RESOURCE_MAX'].astype(int)
    df_m_1['U_THEORY'] = df_m_1['RESOURCE_THEORY'] / df_m_1['RESOURCE'] * 100
    # 按理论U降序，资源量升序排列
    df_m_1s = df_m_1.sort_values(by=['U_THEORY', 'RESOURCE'], ascending=[False, False])
    df_m_1s = df_m_1s.reset_index(drop=True)
    machine_name_list = df_m_1s['MACHINE_NAME'].tolist()
    machine_no_list = df_m_1s['MACHINE_NO'].tolist()
    m1 = len(machine_name_list)
    # 生成副本df
    df_c = pd.DataFrame(columns=['COPY_NAME', 'SERVICE_NAME', 'COPY_SIZE', 'ISOLATION', 'COLUMN_INDEX'])
    dict_c = {}
    copy_name_list = []
    for index, row in df_s.iterrows():
        copy_num_tmp = int(row['COPY_NUM'])
        for i in range(1, copy_num_tmp + 1):
            copy_name_tmp = str(row['SERVICE_NAME']) + 'C' + str(i)
            dict_c['COPY_NAME'] = copy_name_tmp
            dict_c['SERVICE_NAME'] = row['SERVICE_NAME']
            dict_c['COPY_SIZE'] = row['COPY_SIZE']
            dict_c['ISOLATION'] = row['ISOLATION']
            dict_c['COLUMN_INDEX'] = len(copy_name_list)
            new_row = pd.Series(dict_c)
            df_c = df_c.append(new_row, ignore_index=True)
            copy_name_list.append(copy_name_tmp)
    df_c_00 = df_c.copy()
    df_c_00['FLAG'] = 0
    # 副本数量
    copy_count = len(copy_name_list)
    print('副本数量:')
    print(copy_count)
    # 生成初始分配矩阵
    x_array = np.zeros((m1, copy_count))
    # 生成初始主机资源矩阵
    df_m_2 = df_m_1s.copy()
    df_m_2s = df_m_2.sort_values(by='MACHINE_NO', ascending=True)
    df_m_2s = df_m_2s.reset_index(drop=True)
    df_m_2_tmp = df_m_2s[['MACHINE_NAME', 'RESOURCE_THEORY']]
    # df_m_2_tmp = df_m_2s[['MACHINE_NO', 'MACHINE_NAME', 'RESOURCE_THEORY']]
    # df_m_2_tmp.rename(columns={'MACHINE_NO': 'ROW_INDEX'}, inplace=True)
    resource_array = df_m_2_tmp.values
    best_x_array = x_array.copy()
    best_resource_array = resource_array.copy()
    # 对主机数量初步缩减
    df_s_1 = df_s.copy()
    df_s_1 = df_s_1.reset_index(drop=False)
    df_s_1.rename(columns={'index': 'SERVICE_NO'}, inplace=True)
    df_s_1['S_RESOURCE'] = df_s_1['COPY_NUM'] * df_s_1['COPY_SIZE']
    sum_sr = df_s_1['S_RESOURCE'].sum()
    sum_mr_tmp = 0
    count_m_tmp = 0
    for index, row in df_m_1s.iterrows():
        sum_mr_tmp += row['RESOURCE_THEORY']
        count_m_tmp += 1
        if sum_mr_tmp >= sum_sr:
            break
    # 备用两台机器
    if m1 >= count_m_tmp + 2:
        m2 = count_m_tmp + 2
    else:
        m2 = m1
    # 分配反亲和服务
    # 分配最大副本数量的反亲和服务
    def func(x_array_func, resource_array_func, df_func):
        x_array = x_array_func.copy()
        resource_array = resource_array_func.copy()
        df_c_0 = df_func.copy()
        # 主机数量进一步确认
        df_resource = pd.DataFrame(resource_array, columns=['MACHINE_NAME', 'RESOURCE_T_LEFT'])
        df_s_3['S_RESOURCE'] = df_s_3['COPY_NUM'] * df_s_3['COPY_SIZE']
        df_s_4 = df_s_3[df_s_3['ISOLATION'] == 0]
        success = df_s_4.empty is False
        # success = True
        if success is False:
            print('没有非反亲和服务')
        else:
            df_s_4 = df_s_4.reset_index(drop=True)
            sum_sr2 = df_s_4['S_RESOURCE'].sum()
            sum_mr_tmp2 = 0
            count_m_tmp2 = 0
            df_m_3 = df_m_1s.copy()
            df_m_3 = df_m_3.reset_index(drop=False)
            df_m_3.rename(columns={'index': 'ORDER_NO'}, inplace=True)
            v = ['MACHINE_NAME']
            df_m_3 = pd.merge(df_m_3, df_resource, on=v, how='left')
            df_m_3['RANK'] = df_m_3['U_THEORY'].rank(method='dense', ascending=False)
            df_m_3 = df_m_3.sort_values(by='ORDER_NO', ascending=True)
            df_m_3 = df_m_3.reset_index(drop=True)
            for index, row in df_m_3.iterrows():
                sum_mr_tmp2 += row['RESOURCE_T_LEFT']
                count_m_tmp2 += 1
                if sum_mr_tmp2 >= sum_sr2:
                    break
            # 备用两台机器
            if m1 >= count_m_tmp2 + 2:
                m3 = count_m_tmp2 + 2
            else:
                m3 = m1
            # 构建副本大小列表、数量列表
            grouped_sum = df_s_4.groupby('COPY_SIZE')['COPY_NUM'].sum()
            grouped_df = grouped_sum.reset_index()
            grouped_df = grouped_df.sort_values(by='COPY_SIZE', ascending=False)
            grouped_df = grouped_df.reset_index(drop=True)
            size_list = grouped_df['COPY_SIZE'].tolist()
            num_list = grouped_df['COPY_NUM'].tolist()
            min_size = grouped_df['COPY_SIZE'].min()
            df_m_4 = df_m_3.head(m3)
            # 初步限制动态规划的上限，不够后续再补充到新上限
            mr_max = df_m_4['RESOURCE_T_LEFT'].max()
            size_list_str = [str(int(i)) for i in size_list]

            dp_dict = {}
            for i in range(0, len(size_list)):
                size_tmp = int(size_list[i])
                size_tmp_str = str(size_tmp)
                array_tmp = array([[0] * len(size_list)], dtype=float)
                array_tmp[0][i] = 1
                # dp_dict[size_tmp_str] = array_tmp
                df_dp_tmp = pd.DataFrame(array_tmp, columns=size_list_str)
                dp_dict[size_tmp_str] = df_dp_tmp

            def fenpei(dp_dict0, n0, n):
                for i in range(int(n0), int(n + 1)):
                    key_tmp = str(i)
                    if key_tmp in dp_dict0:
                        continue
                    else:
                        df_dp_tmp0 = pd.DataFrame(columns=size_list_str)
                        for j in range(0, len(size_list)):
                            size_tmp2 = int(size_list[j])
                            if i % size_tmp2 == 0:
                                array_tmp = array([[0] * len(size_list)], dtype=float)
                                array_tmp[0][j] = int(i / size_tmp2)
                                # dp_dict0[size_tmp_str] = array_tmp
                                df_dp_tmp1 = pd.DataFrame(array_tmp, columns=size_list_str)
                                df_dp_tmp0 = pd.concat([df_dp_tmp0, df_dp_tmp1], axis=0)
                                df_dp_tmp0 = df_dp_tmp0.reset_index(drop=True)
                        for j in range(0, len(size_list)):
                            ####
                            size_tmp2 = int(size_list[j])
                            key_tmp2 = str(int(i - size_tmp2))
                            if key_tmp2 in dp_dict0:
                                df_dp_tmp1 = dp_dict0[key_tmp2].copy()
                                df_dp_tmp1[str(size_tmp2)] += 1
                                df_dp_tmp0 = pd.concat([df_dp_tmp0, df_dp_tmp1], axis=0)
                                df_dp_tmp0 = df_dp_tmp0.reset_index(drop=True)
                        df_dp_tmp = df_dp_tmp0.drop_duplicates()
                        df_dp_tmp = df_dp_tmp.reset_index(drop=True)
                        success = df_dp_tmp.empty is False
                        # success = True
                        if success is False:
                            # print('空的')
                            continue
                        else:
                            dp_dict0[key_tmp] = df_dp_tmp
                return dp_dict0

            fenpei_dict = fenpei(dp_dict, min_size, mr_max)
            # 开始分配
            rank_max = int(df_m_3['RANK'].max())
            columns_list = size_list_str.copy()
            columns_list.append('MACHINE_NAME')
            columns_list.append('MACHINE_NO')
            df_fp_out = pd.DataFrame(columns=columns_list)
            df_m_6 = df_m_3.copy()
            for i in range(1, rank_max + 1):
                flag = False
                df_m_5 = df_m_3[df_m_3['RANK'] == i]
                df_m_5 = df_m_5.reset_index(drop=True)
                u_theory_tmp = df_m_5.loc[0]['U_THEORY']
                df_m_52 = df_m_6[df_m_6['RANK'] <= i]
                df_m_52 = df_m_52.reset_index(drop=True)
                df_m_53 = pd.DataFrame(
                    columns=['ORDER_NO', 'MACHINE_NO', 'MACHINE_NAME', 'RESOURCE', 'RANK', 'RT', 'NEW_RT', 'RTL',
                             'NEW_RTL'])
                for index, row in df_m_52.iterrows():
                    m53_dict = {}
                    j_max = row['RESOURCE_THEORY'] - u_theory_tmp / 100 * row['RESOURCE']
                    j_max = int(j_max)
                    print(j_max)
                    for j in range(0, j_max + 1):
                        m53_dict['ORDER_NO'] = row['ORDER_NO']
                        m53_dict['MACHINE_NO'] = row['MACHINE_NO']
                        m53_dict['MACHINE_NAME'] = row['MACHINE_NAME']
                        m53_dict['RESOURCE'] = row['RESOURCE']
                        m53_dict['RANK'] = row['RANK']
                        m53_dict['RT'] = row['RESOURCE_THEORY']
                        m53_dict['NEW_RT'] = row['RESOURCE_THEORY'] - j
                        m53_dict['RTL'] = row['RESOURCE_T_LEFT']
                        m53_dict['NEW_RTL'] = row['RESOURCE_T_LEFT'] - j
                        new_row = pd.Series(m53_dict)
                        df_m_53 = df_m_53.append(new_row, ignore_index=True)
                df_m_53['U_THEORY'] = df_m_53['NEW_RT'] / df_m_53['RESOURCE'] * 100
                # df_m_53s = df_m_53.sort_values(by='U_THEORY', ascending=False)
                df_m_53s = df_m_53.sort_values(by=['U_THEORY', 'RESOURCE'], ascending=[False, False])
                df_m_53s = df_m_53s.reset_index(drop=True)
                df_m_53s.drop(['RT'], axis=1, inplace=True)
                df_m_53s.drop(['RTL'], axis=1, inplace=True)
                df_m_53s.rename(columns={'NEW_RT': 'RESOURCE_THEORY'}, inplace=True)
                df_m_53s.rename(columns={'NEW_RTL': 'RESOURCE_T_LEFT'}, inplace=True)
                for index, row in df_m_53s.iterrows():
                    # print(index)
                    fp_dict = {}
                    key_tmp_int = int(row['RESOURCE_T_LEFT'])
                    key_tmp = str(key_tmp_int)
                    order_no_tmp = row['ORDER_NO']
                    machine_no_tmp = row['MACHINE_NO']
                    machine_name_tmp = row['MACHINE_NAME']
                    print(key_tmp)
                    if key_tmp_int > mr_max:
                        print('需要补充dp数组')
                        fenpei_dict = fenpei(fenpei_dict, mr_max, key_tmp_int)
                    if key_tmp in fenpei_dict:
                        print('dp已有')
                        fp_tmp = fenpei_dict[key_tmp]
                        clean_str_start = 'fp_tmp0 = fp_tmp['
                        clean_str_end = ']'
                        ldict1 = {}
                        for j in range(0, len(size_list_str)):
                            size_tmp_str = size_list_str[j]
                            num_tmp = num_list[j]
                            exec('''clean_str1 = "(fp_tmp['{}'] <= {})"'''.format(size_tmp_str, num_tmp), locals(),
                                 ldict1)
                            clean_str1 = ldict1["clean_str1"]
                            if j == 0:
                                clean_str_start = clean_str_start + clean_str1
                            else:
                                clean_str_start = clean_str_start + ' & ' + clean_str1
                        clean_str = clean_str_start + clean_str_end
                        print(clean_str)
                        exec(clean_str, locals(), ldict1)
                        fp_tmp0 = ldict1["fp_tmp0"]
                        success = fp_tmp0.empty is False
                        # success = True
                        if success is False:
                            print('没有满足条件的')
                            print('等同dp没有')
                            continue
                        else:
                            fp_tmp0s = fp_tmp0.sort_values(by=size_list_str, ascending=False)
                            fp_tmp0s = fp_tmp0s.reset_index(drop=True)
                            fp_dict = fp_tmp0s.iloc[0].to_dict()
                            # 记录该主机分配情况并更新num_list
                            fp_dict['ORDER_NO'] = order_no_tmp
                            fp_dict['MACHINE_NAME'] = machine_name_tmp
                            fp_dict['MACHINE_NO'] = machine_no_tmp
                            new_row = pd.Series(fp_dict)
                            df_fp_out = df_fp_out.append(new_row, ignore_index=True)
                            df_m_6 = df_m_6[df_m_6['MACHINE_NAME'] != machine_name_tmp]
                            df_m_6 = df_m_6.reset_index(drop=True)
                            min_resource_t_left = df_m_6['RESOURCE_T_LEFT'].min()
                            for j in range(0, len(size_list_str)):
                                size_tmp_str = size_list_str[j]
                                fp_num_tmp = fp_tmp0s.loc[0][size_tmp_str]
                                num_list[j] -= fp_num_tmp
                            print(num_list)
                            # 每次更新完num_list接一个判断，剩余物品是否还能装满某个机器
                            r_0 = 0
                            for j in range(0, len(size_list)):
                                r_tmp = size_list[j] * num_list[j]
                                r_0 += r_tmp
                            if r_tmp <= min_resource_t_left:
                                # df_m_6s = df_m_6.sort_values(by='RESOURCE', ascending=True)
                                # 优先放放过东西的
                                df_m_61 = df_m_6.copy()

                                def __cal_flag(x):
                                    if x.RESOURCE_T_LEFT == x.RESOURCE_THEORY:
                                        rst = 1
                                    else:
                                        rst = 0
                                    return rst

                                df_m_61['FLAG'] = df_m_61.apply(lambda x: __cal_flag(x), axis=1)
                                df_m_6s = df_m_61.sort_values(by=['FLAG', 'RESOURCE', 'ORDER_NO'],
                                                              ascending=[True, True, True])
                                # 优先放小的
                                df_m_6s = df_m_6s.reset_index(drop=True)
                                for j in range(0, len(size_list_str)):
                                    size_tmp_str = size_list_str[j]
                                    fp_dict[size_tmp_str] = num_list[j]
                                fp_dict['ORDER_NO'] = df_m_6s.loc[0]['ORDER_NO']
                                fp_dict['MACHINE_NAME'] = df_m_6s.loc[0]['MACHINE_NAME']
                                fp_dict['MACHINE_NO'] = df_m_6s.loc[0]['MACHINE_NO']
                                new_row = pd.Series(fp_dict)
                                df_fp_out = df_fp_out.append(new_row, ignore_index=True)
                                print('分配完毕')
                                flag = True
                                break
                            # 不能的话，找最小的主机装了
                            else:
                                continue
                            # 能的话继续
                    else:
                        print('dp没有')
                        print('将同一rank的先循环掉')
                        continue
                print('该rank循环完毕考虑下一rank')
                if flag:
                    break
                continue
            # 解析分配方案
            df_s_5 = df_s_4.copy()
            df_s_5 = df_s_5.reset_index(drop=False)
            df_s_5.rename(columns={'index': 'ORDER_NO2'}, inplace=True)
            for index, row in df_fp_out.iterrows():
                row_index_tmp = int(row['ORDER_NO'])
                for j in range(0, len(size_list_str)):
                    size_tmp_str = size_list_str[j]
                    size_tmp = int(size_tmp_str)
                    fp_num_tmp = int(row[size_tmp_str])
                    df_s_51 = df_s_5[df_s_5['COPY_SIZE'] == size_tmp]
                    df_s_51 = df_s_51.reset_index(drop=True)
                    for index2, row2 in df_s_51.iterrows():
                        service_name_tmp = row2['SERVICE_NAME']
                        copy_num_tmp = row2['COPY_NUM']
                        order_no_tmp = row2['ORDER_NO2']
                        if copy_num_tmp >= fp_num_tmp:
                            df_s_5.loc[order_no_tmp, 'COPY_NUM'] -= fp_num_tmp
                            df_c_1 = df_c_0[(df_c_0['SERVICE_NAME'] == service_name_tmp) & (df_c_0['FLAG'] == 0)]
                            df_c_1 = df_c_1.reset_index(drop=True)
                            df_c_2 = df_c_1.head(fp_num_tmp)
                            c_index_list = df_c_2['COLUMN_INDEX'].tolist()
                            for column_index_tmp in c_index_list:
                                x_array[row_index_tmp, column_index_tmp] = 1
                                df_c_0.loc[column_index_tmp, 'FLAG'] = 1
                            break
                        else:
                            df_s_5.loc[order_no_tmp, 'COPY_NUM'] = 0
                            fp_num_tmp -= copy_num_tmp
                            df_c_3 = df_c_0[(df_c_0['SERVICE_NAME'] == service_name_tmp) & (df_c_0['FLAG'] == 0)]
                            df_c_3 = df_c_3.reset_index(drop=True)
                            c_index_list = df_c_3['COLUMN_INDEX'].tolist()
                            for column_index_tmp in c_index_list:
                                x_array[row_index_tmp, column_index_tmp] = 1
                                df_c_0.loc[column_index_tmp, 'FLAG'] = 1
                            continue
            # print(x_array)
            return x_array,resource_array,df_c_0


    df_s_2 = df_s_1.copy()
    df_s_3 = df_s_1.copy()
    df_s_2 = df_s_2[df_s_2['ISOLATION'] == 1]
    success = df_s_2.empty is False
    # success = True
    if success is False:
        print('没有反亲和服务，直接考虑非反亲和服务')
    else:
        df_s_2s = df_s_2.sort_values(by='COPY_NUM', ascending=False)
        df_s_2s = df_s_2s.reset_index(drop=True)
        cn_max = df_s_2s.loc[0]['COPY_NUM']
        s2n = len(df_s_2s.index)
        #阈值暂定为3，先设成0方便调试
        if s2n <= 3 and max(cn_max, m2) <= 5:
            print('全排列找最优,有时间待开发')
            df_s_tmp = df_s.copy()
            df_s_tmp1 = df_s_tmp[df_s_tmp['ISOLATION'] == 1]
            # 判断是否有需要隔离的服务
            sorted_df_s_tmp1 = df_s_tmp1.sort_values(by='COPY_NUM', ascending=False)
            sorted_df_s_tmp1 = sorted_df_s_tmp1.reset_index(drop=True)
            row_index_list = list(range(int(max(cn_max, m2))))
            combinations_dict = {}
            combo_count_list = []
            for index, row in sorted_df_s_tmp1.iterrows():
                service_name_tmp = row['SERVICE_NAME']
                copy_num_tmp = int(row['COPY_NUM'])
                combinations_list_tmp = list(combinations(row_index_list, copy_num_tmp))
                combinations_dict[service_name_tmp] = combinations_list_tmp
                combo_count_list.append(len(combinations_list_tmp))
            j_count = reduce((lambda x, y: x * y), combo_count_list, 1)
            i_service_name_list = sorted_df_s_tmp1['SERVICE_NAME'].tolist()
            plan_list = []
            for j in range(0, j_count):
                plan_dict_tmp = {}
                quotient = j
                for k in range(0, len(combo_count_list)):
                    service_name_tmp = i_service_name_list[k]
                    dividend = quotient  # 被除数
                    divisor = combo_count_list[k]  # 除数
                    quotient, remainder = divmod(dividend, divisor)
                    # print(f"商: {quotient}")
                    # print(f"余数: {remainder}")
                    plan_dict_tmp[service_name_tmp] = combinations_dict[service_name_tmp][remainder]
                    # print('stop')
                plan_list.append(plan_dict_tmp)
            for i in range(0, len(plan_list)):
                plan_dict_tmp = plan_list[i]
                print(f"方案: {i}")
                tmp_x_array = x_array.copy()
                tmp_resource_array = resource_array.copy()
                for j in range(0, len(i_service_name_list)):
                    i_service_name_tmp = i_service_name_list[j]
                    df_c_tmp = df_c[df_c['SERVICE_NAME'] == i_service_name_tmp]
                    df_c_tmp = df_c_tmp.reset_index(drop=True)
                    combo_tmp = plan_dict_tmp[i_service_name_tmp]
                    copy_size_tmp = sorted_df_s_tmp1.loc[j]['COPY_SIZE']
                    for k in range(0, len(combo_tmp)):
                        # row_index_tmp = int(combo_tmp[k])
                        print(int(combo_tmp[k]))
                        row_index_tmp = machine_no_list[int(combo_tmp[k])]
                        column_index_tmp = int(df_c_tmp.loc[k]['COLUMN_INDEX'])
                        tmp_x_array[row_index_tmp, column_index_tmp] = 1
                        column_index_tmp1 = df_c_tmp.loc[int(combo_tmp[k]), 'COLUMN_INDEX']
                        df_c_00.loc[column_index_tmp1, 'FLAG'] = 1
                        tmp_resource_array[row_index_tmp, 1] -= copy_size_tmp
                print('finish')
                # 分配方案与当前最优方案对比，保留最优作为新最优
                tmp_x_array, tmp_resource_array, best_c_0 = func(tmp_x_array,tmp_resource_array,df_c_0)
                df_c_00 = df_c[df_c['ISOLATION'] == 0]
                sorted_df_c_0 = df_c_00.sort_values(by='COPY_SIZE', ascending=False)
                sorted_df_c_0 = sorted_df_c_0.reset_index(drop=True)
                df_m_0 = pd.DataFrame(tmp_resource_array,
                                      columns=['MACHINE_NAME', 'RESOURCE_L'])
                v = ['MACHINE_NAME']
                df_m_0 = pd.merge(df_m_0, df_m_1, on=v, how='left')
                df_m_0.drop(['RESOURCE_MAX'], axis=1, inplace=True)
                df_m_0.drop(['RESOURCE_THEORY'], axis=1, inplace=True)
                df_m_0.drop(['U_THEORY'], axis=1, inplace=True)
                df_m_0.rename(columns={'MACHINE_NO': 'ROW_INDEX'}, inplace=True)
                sorted_df_m_0 = df_m_0.sort_values(by='RESOURCE_L', ascending=True)
                sorted_df_m_0 = sorted_df_m_0.reset_index(drop=True)
                tmp_df_m_0 = sorted_df_m_0.copy()
                for index, row in sorted_df_c_0.iterrows():
                    # print('副本名:')
                    # print(row['COPY_NAME'])
                    tmp_machine_name_list = tmp_df_m_0['MACHINE_NAME'].tolist()
                    column_index_tmp2 = int(row['COLUMN_INDEX'])
                    for l in range(0, len(tmp_machine_name_list)):
                        tmp_machine_name = tmp_machine_name_list[l]
                        tmp_machine_resource_a = tmp_df_m_0.loc[l]['RESOURCE_L']
                        row_index_tmp2 = int(tmp_df_m_0.loc[l]['ROW_INDEX'])
                        if row['COPY_SIZE'] <= tmp_machine_resource_a:
                            tmp_x_array[row_index_tmp2, column_index_tmp2] = 1
                            tmp_resource_array[row_index_tmp2, 1] = tmp_resource_array[row_index_tmp2, 1] - row['COPY_SIZE']
                            df_m_02 = pd.DataFrame(tmp_resource_array,
                                                   columns=['MACHINE_NAME', 'RESOURCE_L'])
                            v = ['MACHINE_NAME']
                            df_m_02 = pd.merge(df_m_02, df_m_1, on=v, how='left')
                            df_m_02.drop(['RESOURCE_MAX'], axis=1, inplace=True)
                            df_m_02.drop(['RESOURCE_THEORY'], axis=1, inplace=True)
                            df_m_02.drop(['U_THEORY'], axis=1, inplace=True)
                            df_m_02.rename(columns={'MACHINE_NO': 'ROW_INDEX'}, inplace=True)
                            sorted_df_m_02 = df_m_02.sort_values(by='RESOURCE_L', ascending=True)
                            sorted_df_m_02 = sorted_df_m_02.reset_index(drop=True)
                            tmp_df_m_0 = sorted_df_m_02.copy()
                            break
                        else:
                            continue
                # print('stop')
                df_m_best = pd.DataFrame(best_resource_array,
                                         columns=['MACHINE_NAME', 'RESOURCE_L'])
                v = ['MACHINE_NAME']
                df_m_best = pd.merge(df_m_best, df_m_1, on=v, how='left')
                df_m_best.drop(['RESOURCE_MAX'], axis=1, inplace=True)
                df_m_best.drop(['RESOURCE_THEORY'], axis=1, inplace=True)
                df_m_best.drop(['U_THEORY'], axis=1, inplace=True)
                df_m_best.rename(columns={'MACHINE_NO': 'ROW_INDEX'}, inplace=True)
                df_m_tmp1 = pd.DataFrame(tmp_resource_array,
                                      columns=['MACHINE_NAME', 'RESOURCE_L1'])
                v = ['MACHINE_NAME']
                df_m_tmp1 = pd.merge(df_m_tmp1, df_m_1, on=v, how='left')
                df_m_tmp1.drop(['RESOURCE_MAX'], axis=1, inplace=True)
                df_m_tmp1.drop(['RESOURCE_THEORY'], axis=1, inplace=True)
                df_m_tmp1.drop(['U_THEORY'], axis=1, inplace=True)
                df_m_tmp1.rename(columns={'MACHINE_NO': 'ROW_INDEX'}, inplace=True)
                df_m_best.drop(['ROW_INDEX'], axis=1, inplace=True)
                df_m_tmp1.drop(['ROW_INDEX'], axis=1, inplace=True)
                df_m_best.drop(['MACHINE_NAME'], axis=1, inplace=True)
                df_m_tmp1.drop(['MACHINE_NAME'], axis=1, inplace=True)
                df_m_best['U'] = (df_m_best['RESOURCE'] * df_m_best['U_MAX'] / 100 - df_m_best['RESOURCE_L']) / df_m_best[
                    'RESOURCE'] * 100
                df_m_tmp1['U1'] = (df_m_tmp1['RESOURCE'] * df_m_tmp1['U_MAX'] / 100 - df_m_tmp1['RESOURCE_L1']) / df_m_tmp1['RESOURCE'] * 100
                df_m_best.drop(['RESOURCE_L'], axis=1, inplace=True)
                df_m_tmp1.drop(['RESOURCE_L1'], axis=1, inplace=True)
                df_m_best.drop(['RESOURCE'], axis=1, inplace=True)
                df_m_tmp1.drop(['RESOURCE'], axis=1, inplace=True)
                sorted_df_m_best = df_m_best.sort_values(by='U', ascending=False)
                sorted_df_m_best = sorted_df_m_best.reset_index(drop=True)
                sorted_df_m_tmp1 = df_m_tmp1.sort_values(by='U1', ascending=False)
                sorted_df_m_tmp1 = sorted_df_m_tmp1.reset_index(drop=True)

                sorted_df_m_best = sorted_df_m_best.reset_index(drop=False)
                sorted_df_m_best.rename(columns={'index': 'NO'}, inplace=True)
                sorted_df_m_tmp1 = sorted_df_m_tmp1.reset_index(drop=False)
                sorted_df_m_tmp1.rename(columns={'index': 'NO'}, inplace=True)
                v = ['NO']
                df_m_judge = pd.merge(sorted_df_m_best, sorted_df_m_tmp1, on=v, how='left')

                for index, row in df_m_judge.iterrows():
                    if row['U1'] == row['U']:
                        print('方案旗鼓相当，继续比较')
                        continue
                    elif row['U1'] > row['U'] or row['U1'] == 0:
                        print('新方案更好，将新方案替换最优方案')
                        best_x_array = tmp_x_array.copy()
                        best_resource_array = tmp_resource_array.copy()
                        break
                    else:
                        print('原方案更好，考虑下一方案')
                        break
        else:
            print('近似算法')
            for index, row in df_s_2s.iterrows():
                print(index)
                cn_tmp = row['COPY_NUM']
                service_name_tmp = row['SERVICE_NAME']
                service_no_tmp = row['SERVICE_NO']
                copy_size_tmp = row['COPY_SIZE']
                df_c_tmp = df_c[df_c['SERVICE_NAME'] == service_name_tmp]
                df_c_tmp = df_c_tmp.reset_index(drop=True)
                if cn_tmp >= m1:
                    print('反亲和副本数量超过所有主机数')
                    cn_a = 0
                    for i in range(0, int(m1)):
                        row_index_tmp2 = machine_no_list[int(i)]
                        if resource_array[row_index_tmp2, 1] >= copy_size_tmp:
                            column_index_tmp1 = df_c_tmp.loc[i, 'COLUMN_INDEX']
                            x_array[i, column_index_tmp1] = 1
                            df_c_00.loc[column_index_tmp1, 'FLAG'] = 1
                            resource_array[row_index_tmp2, 1] -= copy_size_tmp
                            cn_a += 1
                        else:
                            print('换下一个机器')
                            if i == m1-1:
                                print('超出部分转为非反亲和')
                                print('已经分配好副本数')
                                print(cn_a)
                                df_s_3.loc[service_no_tmp]['ISOLATION'] = 1
                                df_s_3.loc[service_no_tmp]['COPY_NUM'] -= cn_a
                            else:
                                continue
                else:
                    print('反亲和副本数量不超过所有主机数')
                    cn_a = 0
                    for i in range(0, int(cn_tmp)):
                        for j in range(i, int(m1)):
                            row_index_tmp2 = machine_no_list[int(j)]
                            if resource_array[row_index_tmp2, 1] >= copy_size_tmp:
                                column_index_tmp1 = df_c_tmp.loc[i]['COLUMN_INDEX']
                                x_array[i, column_index_tmp1] = 1
                                print(df_c_00.loc[column_index_tmp1, 'FLAG'])
                                df_c_00.loc[column_index_tmp1, 'FLAG'] = 1
                                print(df_c_00.loc[column_index_tmp1, 'FLAG'])
                                resource_array[row_index_tmp2, 1] -= copy_size_tmp
                                cn_a += 1
                                break
                            else:
                                print('换下一个机器')
                                if j == int(m1-1):
                                    print('超出部分转为非反亲和')
                                    print('已经分配好副本数')
                                    print(cn_a)
                                    df_s_3.loc[service_no_tmp]['ISOLATION'] = 1
                                    df_s_3.loc[service_no_tmp]['COPY_NUM'] -= cn_a
                                else:
                                    continue
    print('完成反亲和分配')
    best_x_array, best_resource_array, best_c_0 = func(x_array, resource_array, df_c_00)
    x_array = best_x_array
    resource_array = best_resource_array
    df_c_0 = best_c_0
    # 统计成服务主机
    t_x_array = x_array.T
    df_best_x = pd.DataFrame(t_x_array, columns=machine_name_list)
    df_x = df_best_x.copy()
    df_x['COPY_NAME'] = copy_name_list
    v = ['COPY_NAME']
    df_x_merge = pd.merge(df_x, df_c, on=v, how='left')
    df_x_merge.drop(['COPY_SIZE'], axis=1, inplace=True)
    df_x_merge.drop(['ISOLATION'], axis=1, inplace=True)
    df_x_merge.drop(['COLUMN_INDEX'], axis=1, inplace=True)
    df_x_group = df_x_merge.groupby('SERVICE_NAME').sum()
    df_x_group = df_x_group.reset_index(drop=False)
    df_x_group.rename(columns={'index': 'SERVICE_NAME'}, inplace=True)
    v = ['SERVICE_NAME']
    df_x_group = pd.merge(df_x_group, df_s_1, on=v, how='left')
    df_x_group.drop(['S_RESOURCE'], axis=1, inplace=True)
    # 开始乘2转换成整数，最后输出时除2
    df_x_group['COPY_SIZE'] = df_x_group['COPY_SIZE'] / 2
    # df_x_group = df_x_group.sort_values(by='SERVICE_NO', ascending=True)
    # df_x_group = df_x_group.reset_index(drop=True)
    writer = pd.ExcelWriter('best_sx_new.xlsx')
    df_x_group.to_excel(writer, sheet_name='Sheet1', index=False)
    writer.save()
    plan_dict_list = []
    for index, row in df_x_group.iterrows():
        print(index)
        plan_dict_tmp = {}
        for i in range(0, len(machine_name_list)):
            machine_name_tmp = machine_name_list[i]
            service_count_tmp = row[machine_name_tmp]
            plan_dict_tmp[machine_name_tmp] = service_count_tmp
        print(plan_dict_tmp)
        plan_dict_list.append(str(plan_dict_tmp))
    df_sx_new = df_x_group[['SERVICE_NAME', 'SERVICE_NO', 'COPY_NUM', 'COPY_SIZE', 'ISOLATION']]
    df_sx_new['PLAN'] = plan_dict_list
    writer = pd.ExcelWriter('best_sx_new2.xlsx')
    df_sx_new.to_excel(writer, sheet_name='Sheet1', index=False)
    writer.save()
    table_1 = df_sx_new.to_dict(orient='records')
    print('stop')

    return message, table_1

if __name__ == '__main__':
    start = datetime.datetime.now()
    message, table_1 = main(type=1)
    # print(message, table_1)
    elapsed = float((datetime.datetime.now() - start).seconds)
    print("Time Used 4 All ----->>>> %f seconds" % (elapsed))
    print('finish')
